import { getFromStorage, saveToStorage } from "../storage.js";
import { translateDOM } from "../i18n.js";

function computeCompound({
  principal,
  rate,
  periodsPerYear,
  years,
  contribution = 0,
  contributionAtStart = false,
}) {
  const r = rate / periodsPerYear;
  const n = periodsPerYear * years;
  let future = principal * Math.pow(1 + r, n);
  if (contribution !== 0) {
    const factor = (Math.pow(1 + r, n) - 1) / r;
    future += (contributionAtStart ? 1 + r : 1) * contribution * factor;
  }
  return future;
}

export class CompoundCalculator {
  constructor(root) {
    this.root = root;
    this.render();
  }
  async render() {
    this.root.innerHTML = `
      <div class="grid">
        <label><span data-i18n="principal">Principal</span><input id="cpPrincipal" type="number" value="10000" /></label>
        <label><span data-i18n="rate">Rate</span><input id="cpRate" type="number" step="0.01" value="5" /> <span>%</span></label>
        <label><span data-i18n="frequency">Frequency</span>
          <select id="cpFreq">
            <option value="1" data-i18n="yearly">Yearly</option>
            <option value="4" data-i18n="quarterly">Quarterly</option>
            <option value="12" data-i18n="monthly" selected>Monthly</option>
            <option value="365" data-i18n="daily">Daily</option>
          </select>
        </label>
        <label><span data-i18n="years">Years</span><input id="cpYears" type="number" step="0.1" value="10" /></label>
        <label><span data-i18n="contribution">Contribution</span><input id="cpContribution" type="number" step="0.01" value="0" /></label>
        <label><span data-i18n="contribution_timing">Contribution timing</span>
          <select id="cpTiming">
            <option value="end" data-i18n="end_of_period">End of period</option>
            <option value="start" data-i18n="start_of_period">Start of period</option>
          </select>
        </label>
      </div>
      <div class="display" id="cpResult">0</div>
    `;
    this.principalEl = this.root.querySelector("#cpPrincipal");
    this.rateEl = this.root.querySelector("#cpRate");
    this.freqEl = this.root.querySelector("#cpFreq");
    this.yearsEl = this.root.querySelector("#cpYears");
    this.contribEl = this.root.querySelector("#cpContribution");
    this.timingEl = this.root.querySelector("#cpTiming");

    const last = await getFromStorage("compound_prefs");
    if (last) {
      this.principalEl.value = last.principal ?? this.principalEl.value;
      this.rateEl.value = last.rate ?? this.rateEl.value;
      this.freqEl.value = last.periodsPerYear ?? this.freqEl.value;
      this.yearsEl.value = last.years ?? this.yearsEl.value;
      this.contribEl.value = last.contribution ?? this.contribEl.value;
      this.timingEl.value = last.contributionAtStart ? "start" : "end";
    }

    ["input", "change"].forEach((evt) => {
      this.principalEl.addEventListener(evt, () => this.update());
      this.rateEl.addEventListener(evt, () => this.update());
      this.freqEl.addEventListener(evt, () => this.update());
      this.yearsEl.addEventListener(evt, () => this.update());
      this.contribEl.addEventListener(evt, () => this.update());
      this.timingEl.addEventListener(evt, () => this.update());
    });
    translateDOM(this.root);
    this.update();
  }
  async update() {
    const params = {
      principal: Number(this.principalEl.value || "0"),
      rate: Number(this.rateEl.value || "0") / 100,
      periodsPerYear: Number(this.freqEl.value || "1"),
      years: Number(this.yearsEl.value || "0"),
      contribution: Number(this.contribEl.value || "0"),
      contributionAtStart: this.timingEl.value === "start",
    };
    await saveToStorage("compound_prefs", params);
    const future = computeCompound(params);
    this.root.querySelector("#cpResult").textContent = future.toFixed(2);
  }
}
